import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

/**
 * Handles user interaction with listeners.
 * Calls view and model as needed
 * @author Vo, Wu and Wyan.
 *
 */

public class BattleshipController {
	/**
	 * The model that is being display.
	 */
	private BattleshipModel b_model;
	/**
	 * The view that is being display.
	 */
	private BattleshipView b_view;
	/**
	 * Boolean value to indicate if the ship has been placed.
	 */
	private Boolean ships_placed = false;
	/**
	 * Boolean value to flag that it is player 1 turn.
	 */
	private Boolean p1_turn = true;
	/**
	 * Boolean to get the starting point for each ships that are being placed.
	 */
	private Boolean start_point_placement = true;
	/**
	 * Boolean to flag the listener has been changed.
	 */
	boolean changed_listeners = false;
	/**
	 * Counting the number of cells that are used for each ships
	 */
	boolean game_over = false;
	
	private int ship_count;
	/**
	 * The largest length of ship
	 */
	private int current_ship_length = 5;
	private String current_start;
	/**
	 * an array that collects the cells that are occupied by ship
	 */
	private ArrayList<String> endpoints;
	
	/**
	 * Producing battle ship model and view.
	 * @param model <br />
	 * 			the type of the ship
	 * @param view <br />
	 * 			the length that comes if each type of the ship
	 * @require only use the specific type of ships that are allowed to be in the game and the length
	 * @ensure the name of the ship is the correct type of the ship and the length of the ship is correct
	 * 
	 */
	public BattleshipController (BattleshipModel model, BattleshipView view) {
		b_model = model;
		b_view = view;
		PlacementListener place = new PlacementListener();
		AttackListener attack = new AttackListener();

		// Initialize view
		b_view.enableGrid(true);
		b_view.disableGrid(false);

		// Add listeners to view
		b_view.addActionListener(new PlacementListener());
		b_view.addActionListener(new AttackListener());
		
		
	}

	private class AttackListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			if (ships_placed) {
				String clicked_cell = e.getActionCommand();
				System.out.println ("You just clicked: " + clicked_cell);
				game_over = b_model.isGameOver(p1_turn);
				if (!game_over) {
					// Player 1's Attack

					if (b_model.isValidAttack(p1_turn, clicked_cell)) {
						b_model.addUsedCell(p1_turn, clicked_cell);

						// Hit 
						if (b_model.isHit(p1_turn, clicked_cell)) {

							b_view.updateGrid(p1_turn, clicked_cell, "RED");

							// Check for sunk ship
							if (b_model.isSunk(p1_turn, clicked_cell)) {
								b_view.updateLabel("Sunk!");

								// Check for game over
								if (b_model.isGameOver(p1_turn)) {
									game_over = true;
								}
							}
							else {
								b_view.updateLabel("Hit!");
							}
						}

						// Miss
						else {
							b_view.updateGrid(p1_turn, clicked_cell, "YELLOW");
							b_view.updateLabel("Miss!");
						}
						// Change turns 
						if (!game_over) {
							if (p1_turn) {
								p1_turn = false;
							}
							else {
								p1_turn = true;
							}
							b_view.enableGrid(!p1_turn);
							b_view.disableGrid(p1_turn);

						}
					}
					else {
						b_view.updateLabel("You've already attacked this cell, please choose another!");
					}
				}

				else {
					// Print GAME OVER to the label and show all remaining ships
					if (p1_turn) {
						b_view.updateLabel("Game Over! Player 1 Wins!");
						for (String s : b_model.getShipCells(p1_turn)) {
							
						}
					}
					else {
						b_view.updateLabel("Game Over! Player 2 Wins!");
					}

				}
			}
		}
	}
	/**
	 * inner class PlacementListener
	 * When placement is being requested.
	 * 1.  Get the user input from a clicked cell for each type of the battleship
	 * 2.  Call the model to get the appropriate area of the ship
	 * 3.  Get the result from the model.
	 * 4.  Tell view to display the highlighted range
	 * If there was an error, tell View to display it
	 */
	private class PlacementListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			if (!ships_placed) {
				if (p1_turn) {
					String clicked_cell = e.getActionCommand();
					System.out.println ("You just clicked: " + clicked_cell);
					if (start_point_placement) {
						endpoints = b_model.getEndpoints(p1_turn, clicked_cell, current_ship_length);
						if (b_model.isValidPlacement(p1_turn, clicked_cell) && endpoints.size() != 0) {
							b_view.highlightEndpoints(p1_turn, endpoints);
							current_start = clicked_cell;
							start_point_placement = false;

						}
						else {
							b_view.updateLabel("The selected cell is invalid, please choose another cell.");
						}
					}
					else {
						ArrayList<String> altered_endpoints = new ArrayList<String>();
						// Place ships for player 1

						// Print endpoints
						for (String s : endpoints) {
							System.out.println("Valid Point in Set: " + s);
							System.out.println("Clicked: " + clicked_cell);
						}
						
						// Make temp array with converted cells
						for (String s : endpoints) {
							int row = 0;
							char row_char = ' ';
							String new_endpoint = "";
							if (s.charAt(1) == '0') {
								row_char = 'J';
								new_endpoint = Character.toString(row_char) + s.substring(2);
							}else {
								row = s.charAt(0) + 16;
								row_char = (char)row;
								new_endpoint = Character.toString(row_char) + s.substring(1);
							}

							System.out.println("New endpoint: " + new_endpoint);
							altered_endpoints.add(new_endpoint);
						}
						
						if (altered_endpoints.contains(clicked_cell)) {
							if (ship_count == 0) {
								b_model.placeShip(p1_turn, current_start, clicked_cell,  5);
								b_view.dehighlightEndpoints(p1_turn, endpoints);
								b_view.updateLabel("Player 1, Place your battleship!");
								ship_count++;
								current_ship_length = 4;
								start_point_placement = true;
							}
							else if (ship_count == 1) {
								b_model.placeShip(p1_turn, current_start, clicked_cell,  4);
								b_view.dehighlightEndpoints(p1_turn, endpoints);
								b_view.updateLabel("Player 1, Place your cruiser!");
								ship_count++;
								current_ship_length = 3;
								start_point_placement = true;

							}
							else if (ship_count == 2) {
								b_model.placeShip(p1_turn, current_start, clicked_cell,  3);
								b_view.dehighlightEndpoints(p1_turn, endpoints);
								b_view.updateLabel("Player 1, Place your submarine!");
								ship_count++;
								current_ship_length = 3;
								start_point_placement = true;

							}
							else if (ship_count == 3) {
								b_model.placeShip(p1_turn, current_start, clicked_cell,  3);
								b_view.dehighlightEndpoints(p1_turn, endpoints);
								b_view.updateLabel("Player 1, Place your destroyer!");
								ship_count++;
								current_ship_length = 2;
								start_point_placement = true;

							}
							else if (ship_count == 4) {
								b_model.placeShip(p1_turn, current_start, clicked_cell,  2);	
								b_view.dehighlightEndpoints(p1_turn, endpoints);
								b_view.updateLabel("Player 2, Place your aircraft carrier!");
								current_ship_length = 5;
								p1_turn = false;
								ship_count = 0;
								start_point_placement = true;
								b_view.enableGrid(false);
								b_view.disableGrid(true);
							}
						}
						else {
							b_view.updateLabel("Please choose a valid highlighted endpoint!");
						}
					}
				}
				// Place ship for player 2
				else {
					String clicked_cell = e.getActionCommand();
					if (start_point_placement) {
						endpoints = b_model.getEndpoints(p1_turn, clicked_cell, current_ship_length);
						if (b_model.isValidPlacement(p1_turn, clicked_cell) && endpoints.size() != 0) {
							b_view.highlightEndpoints(p1_turn, endpoints);
							current_start = clicked_cell;
							start_point_placement = false;

						}
						else {
							b_view.updateLabel("The selected cell is invalid, please choose another cell.");
						}
					}
					else {
						// Make temp array with converted cells
						ArrayList<String> altered_endpoints = new ArrayList<String>();
						for (String s : endpoints) {
							int row = 0;
							char row_char = ' ';
							String new_endpoint = "";
							if (s.charAt(1) == '0') {
								row_char = 'J';
								new_endpoint = Character.toString(row_char) + s.substring(2);
							}else {
								row = s.charAt(0) + 16;
								row_char = (char)row;
								new_endpoint = Character.toString(row_char) + s.substring(1);
							}

							System.out.println("New endpoint: " + new_endpoint);
							altered_endpoints.add(new_endpoint);
						}
						if (altered_endpoints.contains(clicked_cell)) {
							if (ship_count == 0) {
								b_model.placeShip(p1_turn, current_start, clicked_cell,  5);
								b_view.dehighlightEndpoints(p1_turn, endpoints);
								b_view.updateLabel("Player 2, Place your battleship!");
								current_ship_length = 4;
								ship_count++;
								start_point_placement = true;

							}
							else if (ship_count == 1) {
								b_model.placeShip(p1_turn, current_start, clicked_cell,  4);
								b_view.dehighlightEndpoints(p1_turn, endpoints);
								b_view.updateLabel("Player 2, Place your cruiser!");
								current_ship_length = 3;
								ship_count++;
								start_point_placement = true;

							}
							else if (ship_count == 2) {
								b_model.placeShip(p1_turn, current_start, clicked_cell,  3);
								b_view.dehighlightEndpoints(p1_turn, endpoints);
								b_view.updateLabel("Player 2, Place your submarine!");
								current_ship_length = 3;
								ship_count++;
								start_point_placement = true;

							}
							else if (ship_count == 3) {
								b_model.placeShip(p1_turn, current_start, clicked_cell,  3);
								b_view.dehighlightEndpoints(p1_turn, endpoints);
								b_view.updateLabel("Player 2, Place your destroyer!");
								current_ship_length = 2;
								ship_count++;
								start_point_placement = true;

							}
							else if (ship_count == 4) {
								b_model.placeShip(p1_turn, current_start, clicked_cell,  2);
								b_view.dehighlightEndpoints(p1_turn, endpoints);
								b_view.updateLabel("Player 1, attack!");
								ships_placed = true;
								changed_listeners = true;
								p1_turn = true;
								b_view.enableGrid(false);
								b_view.disableGrid(true);
							}
						}
						else {
							b_view.updateLabel("Please choose a valid highlighted endpoint!");
						}
					}
				}
			}
		}

	}
}
